<template>
  <el-form :model="processForm" class="processForm" :disabled="isDetail">
    <start />
    <arrow @addList="addList" :showAddBtn="addFlag(0)" />
    <el-form-item prop="processList">
      <div
        v-if="processForm"
        v-for="(processItem, processIndex) in processForm.processList"
        :key="processIndex"
      >
        <div class="flex-sb groupBox relative">
          <div :style="{width: '70px', height: '32px', transform: 'translateY(-50%)', left: 0, 'z-index': 999, top: topValue(processItem)}" class="absolute">
            <el-form-item
              prop="processItem.nodeOrder"
              label-width="0"
              v-if="processItem.nodeType === 2 && showChange(processIndex, processItem)"
            >
              <el-input @focus="focusFn" @input="value => changeNodeOrder1(value, processItem)" type="number" v-model="processItem.nodeOrder" />
            </el-form-item>
          </div>
          <div style="width: 70px" class="relative"></div>
          <div
            :class="{
              flex1: true,
              groupCommonClass: true,
              groupClass: processItem.nodeType === 2
            }"
          >
            <el-row>
              <el-col :span="3">
                <el-form-item
                  v-if="processItem.nodeType === 1"
                  prop="processItem.nodeOrder"
                  label="序号"
                  label-width="40px"
                >
                  <el-input type="number" @input="value => changeNodeOrder2(value, processItem)" v-model="processItem.nodeOrder" />
                </el-form-item>
                <el-form-item
                  v-else
                  prop="processItem.groupOrder"
                  label="序号"
                  label-width="40px"
                >
                  <el-input type="number" @input="processItem.groupOrder = parseFloat(processItem.groupOrder)" v-model="processItem.groupOrder" />
                </el-form-item>
              </el-col>
              <el-col :span="isDetail ? 7 : 6">
                <el-form-item
                  prop="processItem.nodeName"
                  label="节点名称"
                  label-width="80px"
                >
                  <el-input v-model.trim="processItem.nodeName" />
                </el-form-item>
              </el-col>
              <el-col :span="isDetail ? 7 : 6">
                <el-form-item
                  prop="processItem.nodeAlias"
                  label="节点别名"
                  label-width="80px"
                >
                  <el-input v-model.trim="processItem.nodeAlias" />
                </el-form-item>
              </el-col>
              <el-col :span="isDetail ? 7 : 6">
                <el-form-item
                  prop="processItem.nodeNameCode"
                  label="节点编码"
                  label-width="80px"
                >
                  <el-input v-model.trim="processItem.nodeNameCode" />
                </el-form-item>
              </el-col>
              <el-col :span="3" class="pl10" v-if="!isDetail">
                <el-button
                  style="width: 15px;"
                  link
                  type="primary"
                  @click="setDialog(processIndex, processItem)"
                  >设置</el-button
                >
                <el-button
                  style="width: 15px;"
                  link
                  type="primary"
                  @click="addItem(processIndex, processItem.nodeOrder)"
                  v-show="processItem.nodeType === 2"
                >
                  <el-icon color="green">
                    <Plus />
                  </el-icon>
                </el-button>
                <el-button style="width: 15px;" link type="primary" v-show="processItem.nodeType !== 2"
                  >&emsp;</el-button
                >
                <el-button
                  style="width: 15px;"
                  link
                  type="primary"
                  @click="delItem(processIndex)"
                  v-show="showMinus(processIndex, processItem)"
                >
                  <el-icon color="red">
                    <Minus />
                  </el-icon>
                </el-button>
                <el-button
                  style="width: 15px;"
                  link
                  type="primary"
                  v-show="!showMinus(processIndex, processItem)"
                  >&emsp;</el-button
                >
              </el-col>
            </el-row>
          </div>
          <div :style="{width: '80px', height: '43px', transform: 'translateY(-50%)', right: 0, 'z-index': 999, top: topValue(processItem)}" class="absolute" v-show="showChange(processIndex, processItem)">
            <el-button
              v-if="!isDetail"
              class="czjz"
              link
              type="primary"
              @click="changeGroup(processIndex, processItem)"
              >{{ processItem.nodeType === 1 ? '转换为组' : '取消组' }}</el-button
            >
            <el-icon
              v-if="!isDetail"
              size="large"
              color="gray"
              class="closeIcon absolute"
              @click="delGroup(processItem.nodeOrder)"
            >
              <CircleClose />
            </el-icon>
          </div>
          <div style="width: 80px"></div>
        </div>
        <arrow
          v-if="showArrow(processIndex, processItem)"
          :showAddBtn="addFlag(processIndex + 1)"
          @addList="addList"
        />
      </div>
    </el-form-item>
    <end />
  </el-form>
  <slot></slot>
</template>

<script setup>
/*导入*/
import start from './components/start/index.vue';
import arrow from './components/arrow/index.vue';
import end from './components/end/index.vue';
import { CircleClose, Plus, Minus } from '@element-plus/icons-vue';
import { ref, toRaw } from 'vue';
import { ElMessage } from 'element-plus'
/*状态*/
const emit = defineEmits(['setDialog']);
const processForm = defineModel();
const currentIdx = ref(
  processForm.value &&
  processForm.value.processList &&
  processForm.value.processList.length || 0
);
const oldValue = ref(null);
const prop = defineProps({
  isDetail: {
    type: Boolean,
    default: false,
  },
});

/*方法*/
const addList = () => {
  processForm.value.processList.push({
    nodeOrder: getMaxNodeOrder(),
    nodeType: 1,
    groupOrder: null,
    nodeName: '',
    nodeAlias: '',
    nodeNameCode: '',
    extend: {}
  });
  currentIdx.value++;
};
const showArrow = (processIndex, processItem) => {
  let idx = null;
  processForm.value.processList.forEach((item, index) => {
    if (item.nodeOrder === processItem.nodeOrder) {
      idx = index;
    }
  })
  return processIndex === idx;
};
const addFlag = (processIndex) => {
  return currentIdx.value === processIndex && !prop.isDetail;
};
const showMinus = (processIndex, processItem) => {
  let idx = null;
  processForm.value.processList.forEach((item, index) => {
    if (idx === null && item.nodeOrder === processItem.nodeOrder) {
      idx = index;
    }
  })
  return processItem.nodeType === 2 && idx !== processIndex;
}
const showChange = (processIndex, processItem) => {
  let idx = null;
  processForm.value.processList.forEach((item, index) => {
    if (idx === null && item.nodeOrder === processItem.nodeOrder) {
      idx = index;
    }
  })
  return processIndex === idx;
}
const changeGroup = (processIndex, processItem) => {
  let type = processItem.nodeType === 2 ? 1 : 2;
  processItem.nodeType = type;
  if (type === 1) { // 取消组
    let idx = 0;
    processForm.value.processList.forEach((item, index) => {
      if (item.nodeOrder === processItem.nodeOrder) {
        if (idx !== 0) {
          item.nodeOrder = getMaxNodeOrder();
        }
        item.nodeType = type;
        item.groupOrder = null;
        idx++;
      }
    })
  }
};
const addItem = (processIndex, nodeOrder) => {
  processForm.value.processList.splice(processIndex + 1, 0, {
    nodeOrder,
    nodeType: 2,
    groupOrder: null,
    nodeName: '',
    nodeAlias: '',
    nodeNameCode: '',
    extend: {}
  });
  currentIdx.value++;
};
const delItem = (processIndex) => {
  processForm.value.processList.splice(processIndex, 1);
  currentIdx.value--;
};
const delGroup = (nodeOrder) => {
  processForm.value.processList = processForm.value.processList.filter(ls => ls.nodeOrder !== nodeOrder);
  currentIdx.value--;
};
const setDialog = (processIndex, processItem) => {
  emit('setDialog', {
    flag: true,
    processIndex,
    processItem
  });
};
const getMaxNodeOrder = () => {
  let maxNodeOrder = null;
  processForm.value.processList.forEach(ls => {
    if (ls.nodeOrder > (maxNodeOrder || 0)) {
      maxNodeOrder = ls.nodeOrder;
    }
  })
  return Math.floor(maxNodeOrder) + 1;
}
const changeNodeOrder1 = (value, processItem) => {
  if (value) {
    processItem.nodeOrder = parseFloat(processItem.nodeOrder);
    processForm.value.processList.forEach(ls => {
      if (ls.nodeOrder === oldValue.value) {
        ls.nodeOrder = parseFloat(value);
      } else if (ls.nodeOrder === parseFloat(value)) {
        ls.nodeType = 2;
      }
    })
    oldValue.value = parseFloat(value);
  } else {
    processForm.value.processList.forEach(ls => {
      if (ls.nodeOrder === "" || ls.nodeOrder === oldValue.value) {
        ls.nodeOrder = getMaxNodeOrder();
        ls.groupOrder = null;
        ls.nodeType = 1;
      }
    })
  }
}
const changeNodeOrder2 = (value, processItem) => {
  if (value) {
    processItem.nodeOrder = parseFloat(processItem.nodeOrder);
    processForm.value.processList.forEach(ls => {
      if (ls.nodeOrder === parseFloat(value) && ls.nodeType === 1) {
        ls.nodeType = 2;
      }
    })
  }
}
const focusFn = e => {
  oldValue.value = parseFloat(e.target.value);
}
const topValue = (processItem) => {
  let idx = 0;
  processForm.value.processList.forEach(ls => {
    if (ls.nodeOrder == processItem.nodeOrder) {
      idx++;
    }
  })
  let top = `${idx * 50}%`;
  return top;
}
// 将数据整理后输出(排列时，外部按nodeOrder顺序，内部按groupOrder顺序)
const handleProcessData = () => {
  let ary = [];
  let data = [];
  let map = new Map();
  processForm.value.processList.forEach(ls => {
    if (map.has(ls.nodeOrder)) {
      map.get(ls.nodeOrder).push(toRaw(ls));
    } else {
      map.set(ls.nodeOrder, [toRaw(ls)]);
    }
  })
  // 内部从小到大排序
  ary = [...map.values()];
  ary.forEach(ls => {
    ls = ls.sort((a, b) => a.groupOrder - b.groupOrder);
  })
  ary.forEach(ls => {
    data.push({
      key: ls[0].nodeOrder,
      value: ls
    })
  })
  data = data.sort((a, b) => a.key - b.key);
  let result = [];
  data.forEach(ls => {
    result.push(...ls.value);
  })
  console.log(result);
  return result;
}
defineExpose({
  handleProcessData,
});
</script>

<style lang="scss">
.processForm {
  &.el-form {
    padding: 10px;
  }

  .el-form-item {
    margin-bottom: 0px;
  }

  .el-form-item__content {
    display: block;
  }
}
</style>

<style lang="scss" scoped>
.processForm {
  text-align: center;
  padding: 0px;
  width: 100%;
  height: 100%;

  .czjz {
    top: 50%;
    left: 0;
    position: absolute;
    transform: translateY(-50%);
  }

  .flex-sb {
    display: flex;
    justify-content: space-between;
  }

  .flex1 {
    flex: 1;
  }

  .pl10 {
    padding-left: 10px;
  }

  .relative {
    position: relative;
  }

  .absolute {
    position: absolute;
  }

  .groupBox {
    .closeIcon {
      cursor: pointer;
      top: -500000px;
      right: -500000px;
    }

    &:hover {
      .closeIcon {
        top: 0%;
        right: 0px;
      }
    }
  }

  .groupCommonClass {
    padding: 5px;
  }

  .groupClass {
    background-color: #cde4f6;
  }
}
</style>
